package com.atguigu.exam.service.impl;


import com.atguigu.exam.entity.ExamRecord;
import com.atguigu.exam.entity.Paper;
import com.atguigu.exam.entity.PaperQuestion;
import com.atguigu.exam.entity.Question;
import com.atguigu.exam.exception.ExamException;
import com.atguigu.exam.mapper.ExamRecordMapper;
import com.atguigu.exam.mapper.PaperMapper;
import com.atguigu.exam.mapper.PaperQuestionMapper;
import com.atguigu.exam.mapper.QuestionMapper;
import com.atguigu.exam.service.PaperQuestionService;
import com.atguigu.exam.service.PaperService;
import com.atguigu.exam.vo.PaperVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.min;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 试卷服务实现类
 */
@Slf4j
@Service
@Transactional
public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements PaperService {

    @Autowired
    QuestionMapper questionMapper;
    @Autowired
    PaperQuestionMapper paperQuestionMapper;
    @Autowired
    PaperQuestionService paperQuestionService;
    @Autowired
    ExamRecordMapper examRecordMapper;

    @Override
    public Paper getDetailById(Integer id) {
        Paper paper = baseMapper.selectById(id);
        List<Question> questionsList = questionMapper.getDetailById(id);
        paper.setQuestions(questionsList);
        return paper;
    }

    @Override
    public Paper createPaper(PaperVo paperVo) {
        boolean exists = baseMapper.exists(new LambdaQueryWrapper<Paper>().eq(Paper::getName, paperVo.getName()));
        if (exists) {
            throw new ExamException(1100, "试卷已经存在，请重新修改试卷名称");
        }
        Paper paper = new Paper();
        BeanUtils.copyProperties(paperVo, paper);
        paper.setStatus("DRAFT");
        Map<Long, BigDecimal> questions = paperVo.getQuestions();
        paper.setQuestionCount(questions.size());
        BigDecimal reduce = questions.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add);
        paper.setTotalScore(reduce);
        baseMapper.insert(paper);
        List<PaperQuestion> collect = questions.entrySet().stream().map(entry -> new PaperQuestion(paper.getId(), entry.getKey(), entry.getValue())).collect(Collectors.toList());
        paperQuestionService.saveBatch(collect);
        return paper;
    }

    @Override
    public Paper updatePaper(Integer id, PaperVo paperVo) {
        Paper paper = baseMapper.selectById(id);
        if ("PUBLISHED".equals(paper.getStatus())) {
            throw new ExamException(1200, "该试卷已经发布，请勿修改");
        }
        boolean exists = baseMapper.exists(new LambdaQueryWrapper<Paper>().eq(Paper::getName, paperVo.getName()));
        if (exists) {
            throw new ExamException(1300, "试卷已经存在，请重新修改试卷名称");
        }
        BeanUtils.copyProperties(paperVo, paper);
        paper.setUpdateTime(null);
        paper.setStatus("DRAFT");
        Map<Long, BigDecimal> questions = paperVo.getQuestions();
        paper.setQuestionCount(questions.size());
        BigDecimal reduce = questions.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add);
        paper.setTotalScore(reduce);
        baseMapper.updateById(paper);
        paperQuestionMapper.delete(new LambdaQueryWrapper<PaperQuestion>().eq(PaperQuestion::getPaperId, id));
        List<PaperQuestion> collect = questions.entrySet().stream().map(entry -> new PaperQuestion(paper.getId(), entry.getKey(), entry.getValue())).collect(Collectors.toList());
        paperQuestionService.saveBatch(collect);
        return paper;
    }

    @Override
    public void updatePaperStatus(Integer id, String status) {
        Long selectCount = examRecordMapper.selectCount(new LambdaQueryWrapper<ExamRecord>().eq(ExamRecord::getStatus, "进行中").eq(ExamRecord::getExamId, id));
        if (selectCount > 0) {
            throw new ExamException(1400, "该试卷有进行中的考试，请勿修改");
        }
        baseMapper.update(null, new LambdaUpdateWrapper<Paper>().eq(Paper::getId, id).set(Paper::getStatus, status));
    }

    @Override
    public void getRemoveById(Integer id) {
        Long selectCount = examRecordMapper.selectCount(new LambdaQueryWrapper<ExamRecord>().eq(ExamRecord::getStatus, "进行中").eq(ExamRecord::getExamId, id));
        if (selectCount > 0) {
            throw new ExamException(1500, "该试卷有进行中的考试，请勿删除");
        }
        baseMapper.deleteById(id);
        paperQuestionMapper.delete(new LambdaQueryWrapper<PaperQuestion>().eq(PaperQuestion::getPaperId, id));
    }
}
